package com.ys.多线程.p6线程同步Lock锁;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 描述: ChangJiangBride  长江大桥对象-共享资源
 *场景：使用Lock对共享资源的加锁和解锁
 *  * 1 创建Lock对象
 *  * 2 为runDongche()方法和runHuoche()方法加锁和解锁
 *
 * Lock是程序级别的锁，可以人为的加锁和解锁，Since JDK5
 *
 * 加锁：通常在try外面，需要调用的方法lock()
 *
 * 解锁：通常在finally里面,需要调用的方法unlock();
 * @author CodeYang
 * @version 2021/1/5 19:23
 */
public class ChangJiangBride {


    /**
     * 创建一个Lock对象对共享资源加锁和解锁
     * true 公平锁 false 非公平锁,默认false
     */
    private Lock lck = new ReentrantLock(true);

    /**
     * 动车通过大桥
     */
    public  void runDongChe(){
        // lock,是手动加锁的,建议在try外面加锁,因为,在try里面加锁,如果加锁之前就出现了异常,那么解锁就会出错

        lck.lock();
        try {
            System.out.print("当前进入时间:"+System.currentTimeMillis());
            // 模动车通过需要5秒
            System.out.println(Thread.currentThread().getName()+"动车正在通过长江大桥,大约需要5秒");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("动车成功通过");
        }finally {
            // 手动解锁: 在finaly里去解锁
            // 好处：加锁和解锁都是我们自己定义的，即使try块出现异常，也能够在finally里面解锁
            lck.unlock();
        }



    }


    /**
     * 货车通过大桥
     */
    public  void runHuoChe(){
        lck.lock();
        try {
            System.out.print("当前进入时间:"+System.currentTimeMillis());
            // 模动车通过需要5秒
            System.out.println(Thread.currentThread().getName()+"货车正在通过长江大桥,大约需要3秒");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("货车成功通过");
        }  finally {
            lck.unlock();
        }


    }
}
